--- lib/libusbhid/parse.c.orig
+++ lib/libusbhid/parse.c
@@ -403,26 +403,28 @@
 				s->loc_count = dval & mask;
 				break;
 			case 10:	/* Push */
+				/* stop parsing, if invalid push level */
+				if ((s->pushlevel + 1) >= MAXPUSH)
+					return (0);
 				s->pushlevel ++;
-				if (s->pushlevel < MAXPUSH) {
-					s->cur[s->pushlevel] = *c;
-					/* store size and count */
-					c->report_size = s->loc_size;
-					c->report_count = s->loc_count;
-					/* update current item pointer */
-					c = &s->cur[s->pushlevel];
-				}
+				s->cur[s->pushlevel] = *c;
+				/* store size and count */
+				c->report_size = s->loc_size;
+				c->report_count = s->loc_count;
+				/* update current item pointer */
+				c = &s->cur[s->pushlevel];
 				break;
 			case 11:	/* Pop */
+				/* stop parsing, if invalid push level */
+				if (s->pushlevel == 0)
+					return (0);
 				s->pushlevel --;
-				if (s->pushlevel < MAXPUSH) {
-					c = &s->cur[s->pushlevel];
-					/* restore size and count */
-					s->loc_size = c->report_size;
-					s->loc_count = c->report_count;
-					c->report_size = 0;
-					c->report_count = 0;
-				}
+				c = &s->cur[s->pushlevel];
+				/* restore size and count */
+				s->loc_size = c->report_size;
+				s->loc_count = c->report_count;
+				c->report_size = 0;
+				c->report_count = 0;
 				break;
 			default:
 				break;
--- sys/dev/usb/usb_hid.c.orig
+++ sys/dev/usb/usb_hid.c
@@ -436,36 +436,36 @@
 				s->loc_count = dval & mask;
 				break;
 			case 10:	/* Push */
+				/* stop parsing, if invalid push level */
+				if ((s->pushlevel + 1) >= MAXPUSH) {
+					DPRINTFN(0, "Cannot push item @ %d\n", s->pushlevel);
+					return (0);
+				}
 				s->pushlevel ++;
-				if (s->pushlevel < MAXPUSH) {
-					s->cur[s->pushlevel] = *c;
-					/* store size and count */
-					c->loc.size = s->loc_size;
-					c->loc.count = s->loc_count;
-					/* update current item pointer */
-					c = &s->cur[s->pushlevel];
-				} else {
-					DPRINTFN(0, "Cannot push "
-					    "item @ %d\n", s->pushlevel);
-				}
+				s->cur[s->pushlevel] = *c;
+				/* store size and count */
+				c->loc.size = s->loc_size;
+				c->loc.count = s->loc_count;
+				/* update current item pointer */
+				c = &s->cur[s->pushlevel];
 				break;
 			case 11:	/* Pop */
+				/* stop parsing, if invalid push level */
+				if (s->pushlevel == 0) {
+					DPRINTFN(0, "Cannot pop item @ 0\n");
+					return (0);
+				}
 				s->pushlevel --;
-				if (s->pushlevel < MAXPUSH) {
-					/* preserve position */
-					oldpos = c->loc.pos;
-					c = &s->cur[s->pushlevel];
-					/* restore size and count */
-					s->loc_size = c->loc.size;
-					s->loc_count = c->loc.count;
-					/* set default item location */
-					c->loc.pos = oldpos;
-					c->loc.size = 0;
-					c->loc.count = 0;
-				} else {
-					DPRINTFN(0, "Cannot pop "
-					    "item @ %d\n", s->pushlevel);
-				}
+				/* preserve position */
+				oldpos = c->loc.pos;
+				c = &s->cur[s->pushlevel];
+				/* restore size and count */
+				s->loc_size = c->loc.size;
+				s->loc_count = c->loc.count;
+				/* set default item location */
+				c->loc.pos = oldpos;
+				c->loc.size = 0;
+				c->loc.count = 0;
 				break;
 			default:
 				DPRINTFN(0, "Global bTag=%d\n", bTag);
